package com.shujichen.utils;

import cn.hutool.extra.spring.SpringUtil;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

public class PoetryCacheRedis {

    private static final RedissonClient CLIENT = SpringUtil.getBean(RedissonClient.class);

    /**
     * 添加缓存
     *
     * @param key  键
     * @param data 值
     */
    public static void put(String key, Object data) {
        put(key, data, 0);
    }

    /**
     * 添加缓存
     *
     * @param key    键
     * @param data   值
     * @param expire 过期时间，单位：秒，0表示无限长
     */
    public static void put(String key, Object data, long expire) {
        RBucket<Object> bucket = CLIENT.getBucket(key);
        if (expire > 0) {
            bucket.set(data, expire, TimeUnit.SECONDS);
        } else {
            bucket.set(data);
        }
    }

    /**
     * 读取缓存
     *
     * @param key 键
     * @return
     */
    public static Object get(String key) {
        RBucket<Object> bucket = CLIENT.getBucket(key);
        return bucket.get();
    }

    /**
     * 读取所有缓存
     *
     * @return
     */
    public static Collection<Object> keys() {
        return StreamSupport.stream(CLIENT
                                .getKeys()
                                .getKeys()
                                .spliterator(),
                        false)
                .collect(Collectors.toList());
    }

    /**
     * 读取所有缓存
     *
     * @return
     */
    public static Collection<Object> values() {
        return StreamSupport.stream(CLIENT.getKeys().getKeys().spliterator(), false)
                .map(key -> {
                    RBucket<Object> bucket = CLIENT.getBucket(key);
                    return bucket.get();
                })
                .filter(Objects::nonNull) // 过滤掉可能为 null 的值
                .collect(Collectors.toList());
    }

    /**
     * 读取所有缓存的键值对
     *
     * @return 包含所有键值对的 Map
     */
    public static Map<Object, Object> maps() {
        return StreamSupport.stream(CLIENT.getKeys().getKeys().spliterator(), false)
                .collect(Collectors.toMap(
                        key -> key,
                        key -> {
                            RBucket<Object> bucket = CLIENT.getBucket(key);
                            return bucket.get();
                        }
                ))
                .entrySet().stream()
                .filter(entry -> entry.getValue() != null) // 过滤掉可能为 null 的值
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    }

    /**
     * 清除缓存
     *
     * @param key 键
     * @return
     */
    public static Object remove(String key) {
        RBucket<Object> bucket = CLIENT.getBucket(key);
        Object value = bucket.get();
        bucket.delete();
        return value;
    }

    /**
     * 查询当前缓存的键值对数量
     *
     * @return
     */
    public static int size() {
        return (int) CLIENT.getKeys().count();
    }

    /**
     * 根据key前缀查询并转换为指定类型的对象列表
     *
     * @param keyPrefix key前缀，如"task:"
     * @param clazz     目标类型
     * @param <T>       泛型类型
     * @return 对象列表
     * @throws IllegalArgumentException 如果类型不匹配
     */
    public static <T> List<T> findByPrefix(String keyPrefix, Class<T> clazz) {
        return StreamSupport.stream(
                        CLIENT.getKeys()
                                .getKeysByPattern(keyPrefix + "*")
                                .spliterator(),
                        false)
                .map(key -> {
                    try {
                        RBucket<Object> bucket = CLIENT.getBucket(key);
                        Object value = bucket.get();
                        if (value == null) {
                            return null;
                        }
                        if (!clazz.isInstance(value)) {
                            throw new IllegalArgumentException(
                                    String.format("Value for key %s is not of type %s",
                                            key, clazz.getName()));
                        }
                        return clazz.cast(value);
                    } catch (Exception e) {
                        // 记录错误日志
                        System.err.println("Error processing key: " + key + ", error: " + e.getMessage());
                        return null;
                    }
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

}
